package com.example.sqldemo.Service;


import com.alibaba.fastjson.JSON;
import com.example.sqldemo.mapper.SqlMapper;
import com.example.sqldemo.pojo.AuditModel;
import com.example.sqldemo.pojo.Pair;
import com.example.sqldemo.pojo.RuleInfo;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.cursor.Cursor;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.*;

@Service
@Slf4j
public class SqlService {


    @Resource
    private SqlMapper sqlMapper;

    @Resource(name = "serviceExecutor")
    private ThreadPoolTaskExecutor executor;

    @Transactional
    public void getAuditData(){
        int count = 0;
        long start = System.currentTimeMillis();
        Cursor<HashMap<String, Object>> result = sqlMapper.getAuditData();
        int currentIndex = result.getCurrentIndex();
        boolean consumed = result.isConsumed();
        Iterator<HashMap<String, Object>> iterator = result.iterator();
        while (iterator.hasNext()) {
            log.info("打印第"+count+"条数据:{}",JSON.toJSONString(iterator.next()));
            count++;
        }
        long end = System.currentTimeMillis();
        log.info("获取500万数据一共耗时 = {}",end-start);
    }

    public void addData() {
        int count = 0;
        int total = 0;
        List<String> nameList = Arrays.asList("haha", "wangwu", "heihei", "lala", "eeeee");
        List<String> addrList = Arrays.asList("西安", "武汉", "长沙", "北京", "天津");
        List<String> valueList = Arrays.asList("1", "2", "3", "4", "5");
        List<Integer> phoneList = Arrays.asList(11111, 22222, 33333, 444444, 555555);
        List<String> userList = Arrays.asList("张三", "王五", "赵四", "老六", "力七");
        List<String> countryList = Arrays.asList("中国", "美国", "英国", "法国", "德国");
        List<String> cityList = Arrays.asList("汉中", "西安", "安康", "榆林", "渭南");
        List<String> createByList = Arrays.asList("啦啦啦", "咯咯咯", "过过过", "咚咚咚", "咔咔咔");

        Random random = new Random();
        ArrayList<AuditModel> list = new ArrayList<>();
        while (total < 5000000) {
            log.info("开始生成第" + total + "条数据!");
            AuditModel auditModel = new AuditModel();
            auditModel.setName(nameList.get(random.nextInt(5)));
            auditModel.setAddr(addrList.get(random.nextInt(5)));
            auditModel.setValue(valueList.get(random.nextInt(5)));
            auditModel.setPhone(phoneList.get(random.nextInt(5)));
            auditModel.setUser(userList.get(random.nextInt(5)));
            auditModel.setCountry(countryList.get(random.nextInt(5)));
            auditModel.setCity(cityList.get(random.nextInt(5)));
            auditModel.setCreateBy(createByList.get(random.nextInt(5)));
            auditModel.setCreateDate(new Date());
            auditModel.setLastUpdateDate(new Date());
            list.add(auditModel);
            if (list.size() == 500) {
                log.info("开始插入第" + count + "批数据!");
                sqlMapper.batchInsert(list);
                list.clear();
                log.info("第" + count + "批数据插入完成!");
                count++;
            }
            total++;
        }

    }

    @Transactional
    public List<HashMap<String, Object>> getData3() {

//        Pair pair1 = new Pair("int", 1);
//        Pair pair2 = new Pair("string", "北京");
//        ArrayList<Pair> params = new ArrayList<>();
//        params.add(pair1);
//        params.add(pair2);
//        String finalSql = getSql(sql, params);
//        System.out.println(finalSql);
        sqlMapper.createTable3();
        Cursor<HashMap<String, Object>> result = sqlMapper.select();
        Iterator<HashMap<String, Object>> iterator = result.iterator();
//        ArrayList<HashMap<String, Object>> successList = new ArrayList<>();
//        ArrayList<HashMap<String, Object>> failureList = new ArrayList<>();
//        AtomicInteger sourceCount = new AtomicInteger(0);
//        AtomicInteger targetCount = new AtomicInteger(0);

        while (iterator.hasNext()) {
            HashMap<String, Object> data = iterator.next();
            executor.execute(new Runnable() {
                @Override
                public void run() {
                    Integer id = (Integer) data.get("id");
                    System.out.println(data);
//                    if (id%2==1){
//                        successList.add(data);
//                        sourceCount.addAndGet(1);
//                    }else {
//                        failureList.add(data);
//                        targetCount.addAndGet(1);
//                    }
                }
            });
            // 如果其中任何一个list的数量到了2个, 那么就打印一次list
//            if (successList.size()==2 || failureList.size() == 2){
//                System.out.println(successList);
//                System.out.println(failureList);
//                successList.clear();
//                failureList.clear();
//            }
        }
        // 打印总数
//        System.out.println(sourceCount);
//        System.out.println(targetCount);
        log.info("打印 result = {}", JSON.toJSONString(result));
        return null;
    }

//    @Transactional
//    public List<HashMap<String, Object>> getData3(String sql) throws InterruptedException {
//
//        Pair pair1 = new Pair("int", 1);
//        Pair pair2 = new Pair("string", "北京");
//        ArrayList<Pair> params = new ArrayList<>();
//        params.add(pair1);
//        params.add(pair2);
//        String finalSql = getSql(sql, params);
//        System.out.println(finalSql);
//        Cursor<HashMap<String, Object>> result = sqlMapper.select(finalSql);
//        Iterator<HashMap<String, Object>> iterator = result.iterator();
//        ArrayList<HashMap<String, Object>> successList = new ArrayList<>();
//        ArrayList<HashMap<String, Object>> failureList = new ArrayList<>();
//        AtomicInteger sourceCount = new AtomicInteger(0);
//        AtomicInteger targetCount = new AtomicInteger(0);
//
//        List<HashMap<String, Object>> list = new ArrayList<>();
//        String taskId = "123";
//        while (iterator.hasNext()) {
//            HashMap<String, Object> data = iterator.next();
//            list.add(data);
//            if (list.size()<4){
//                continue;
//            }
//            // 任务分发, 一次分发2个.
//            int cur = 0;
//            int end = 2;
//            // 任务数量
//            final CountDownLatch taskNum = new CountDownLatch(list.size());
//
//            while (end <= list.size()){
//                List<HashMap<String, Object>> subList = list.subList(cur, end);
//                executor.execute(new Runnable() {
//                    @Override
//                    public void run() {
//                        for (HashMap<String, Object> map : subList) {
//                            try {
//                                log.info("开始执行线程内任务=====");
//                            System.out.println(map);
//
//                                Thread.sleep(11000);
//                            } catch (InterruptedException e) {
//                                e.printStackTrace();
//                            }finally {
//                                if (taskId.equals(taskId)){
//                                    taskNum.countDown();
//                                }
//                            }
//                        }
//                    }
//                });
//                cur = end;
//                end = end +2;
//            }
//            boolean await = taskNum.await(10, TimeUnit.SECONDS);
//            System.out.println("等待结果: "+await);
//            log.info("等待结果: "+await);
//            log.info("任务执行结束");
//        }
//
//
//        return null;
//    }

    private String getSql(String sql, ArrayList<Pair> params) {
        for (int i = 0; i < params.size(); i++) {
            String data = getValueData(params.get(i));
            sql = sql.replaceFirst("\\?", data);
        }
        return sql;
    }

    private String getValueData(Pair param) {
        String value = null;
        switch (param.getKey()) {
            case "string":
                value = "'" + param.getValue() + "'";
                break;
            case "int":
                value = "" + param.getValue();
                break;
            case "double":
                value = "" + param.getValue();
                break;
            case "date":
                SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                String date = format.format(param.getValue());
                value = "'" + date + "'";
                break;
            case "boolean":
                value = Boolean.TRUE.equals((boolean) param.getValue()) ? "1" : "0";
                break;

        }
        return value;
    }

    public void getData2(String sql) {
        ArrayList<Object> list = new ArrayList<>();
        list.add(1);
        List<LinkedHashMap<String, Object>> result = sqlMapper.selectByParams(sql, list);
        System.out.println(result);
    }

    public void createTable(String sql) {
        sqlMapper.createTable(sql);
    }

    public List<HashMap<String, Object>> get2(RuleInfo ruleInfo) {
        List<HashMap<String, Object>> linkedHashMaps = sqlMapper.select2(ruleInfo);
        System.out.println(linkedHashMaps);
        return linkedHashMaps;
    }
}
